package org.geektimes.projects.userweb.hash;

import org.geektimes.projects.userweb.hash.consistent1.HashServiceImpl;
import org.geektimes.projects.userweb.hash.consistent2.HashServiceImpl2;

import java.util.*;

/**
 * @Author: jipeng
 * @Description:
 * @Date: Created in 2021/5/18 7:23
 */
public class TestHashCircle {
    //机器IP节点前缀
    private static final String IP_PREFIX = "192.168.0.";


    public static void main(String[] args) {

        System.out.println("==================plan A=========================");
        planA(new HashServiceImpl());

        System.out.println("=");
        System.out.println("=");
        System.out.println("=");
        System.out.println("=");
        System.out.println("=");
        System.out.println("==================plan B=========================");
        planA( new HashServiceImpl2());
    }


    private static void planA(IHashService hashService){
        //每台真实机器节点上保存的记录条数
        Map<String, Integer> map = new HashMap<>();

        List<Node<String>> nodes = new ArrayList<>();
        for (int i = 1; i <= 10; i++) {
            String ip = IP_PREFIX + i;
            //初始化机器节点上的保存记录条数
            map.put(ip, 0);

            Node<String> node = new Node<>(ip, "node" + i);
            nodes.add(node);
        }

        //每台真实机器引入500个虚拟节点
        ConsistentHash<Node<String>> consistentHash = new ConsistentHash<Node<String>>(hashService, 500, nodes);

        System.out.println("10个节点");
        text(consistentHash, map);

        System.out.println("删除中间第6个节点");
        Node<String> node = nodes.get(5);
        consistentHash.removeNode(node);
        map.remove(node.getIp());

        text(consistentHash, map);

        System.out.println("增加一个 11节点");
        // 加入一个11节点
        String ip = IP_PREFIX + 11;
        map.put(ip, 0);
        node = new Node<>(ip, "node" + 11);

        consistentHash.addNode(node);
        text(consistentHash, map);
    }



    private static void text(ConsistentHash<Node<String>> consistentHash, Map<String, Integer> map) {
        // 将5000条数据尽可能的均匀的存储在10台机器节点上
        for (int i = 0; i < 1000000; i++) {

            //产生一个随机字符串当做一条记录，可以是其他更复杂的业务对象，
            //比如随机字符串相当于对象的业务唯一标识
            String data = UUID.randomUUID().toString() + i;
            //通过记录找到真实的机器节点
            Node<String> node = consistentHash.get(data);

            //在这里可以通过其他工具将记录存储真实机器节点上，比如MemoryCache等
            // ...
            // 每台真实机器节点上保存的记录条数 加1
            map.put(node.getIp(), map.get(node.getIp()) + 1);
        }


        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            System.out.println(entry.getKey() + "节点记录数：" + entry.getValue());
        }

        for(Map.Entry<String,Integer> entry : map.entrySet()){
            map.put(entry.getKey(),0);
        }
    }

}
